Date		:	13 juillet 1991
		Protection	:	MOT DE PASSE
		Programme	:       THE CURSE OF RA
		Outils		:	SOFT-ICE V2.50a 
		Fichier		:	FRED3.COM
		Temps pass�	:	2 HEURES environ...
		Soci�t�		:	RAINBOW ARTS
		Divers	        :	Cr�ation du fichier FRED3.COM
		Origine		:	INDONESIE
		Num�ro		:	107


	Un saut qui tape � l'oeil puisque l'on rep�re tout de suite une
	case m�moire dans laquelle on plave un 1 et qui autrement contient 0.
	C'est classique � la sortie d'un test dans les protections type mot de
	passe.

	CS:1A81 3A04		CMP AL,[SI]
	CS:1A83 7405		JZ  1A8A
	CS:1A85 C606550001	MOV BYTE PTR [0055],01
	CS:1A8A E9E0F6		JMP 116D

	Dans le cas d'une mauvaise r�ponse on place 01 dans DS:0055.
	Ce serait presque trop facile si ce n'�tait que cette chaine n'apparait
	dans aucun fichier du programme !. Je regarde � l'oeil nu le header
	de RA.COM et que vois-je ? Un programme certe compact� mais ni par
	LZEXE, ni par PKLITE. Donc il ne reste que l'ultime solution de
	d�tourner une interruption pour aller modifier le programme � cet
	endroit.
	Je passe le jeu � QUAID avec un blocage sur l'INT 21 et je m'aper�ois
	que la sous-fonction GET TIME ( 2Ch ) est appel�e � chaque fois avant
	que le soft ne demande le mot de passe. 
	Il ne reste plus qu'� adapter un de mes FRED?.COM dans lequel il
	suffira de rechercher le segment CS qui contiendra 74 en 1A83 ou bien
	01 en 1A89 en popant le pointeur de pile.
	
	Ci-dessous le programme FRED3.COM qui intercepte la fonction GET TIME
	de l'INT 21.

 ;	PATCH POUR LE PROGRAMME CURSE OF RA		13 Juillet 1991
 ;	FREDDY_SOFT

 code      segment
           org    100h
           assume cs:code

 start:    jmp    installe	; On va installer la routine r�sidente...

 cr        equ    0dh
 lf        equ    0ah
 flag      equ    02Ch
 adr_ip    equ    1A89h ; En CS:1A89 il suffit de mettre 0.
 patch     equ    0   ; � mettre � la place de 01 en CS:1A89h
 

 instok    db     cr,lf,'    D�tournement de l',39,'INT 21 sous-fonction 2C'
	   db     cr,lf
	   db     '                  ....FREDDY_SOFT....','$'
 drap      db     0,0
 elimine   db     cr,lf,'J',39,'ai en principe tout remis en l',39,'�tat....'
	   db     cr,lf,'$'

 int21     label  dword	; sauvegarde des adresses SEG:OFF de l'INT21 d'origine
 i40off    db     0,0	; OFFSET
 i40seg    db     0,0	; SEGMENT

 tsrint40  proc   far
           jmp short apr�s_id
	   db    'FR'	; On intercalle au d�but du code un identificateur
 apr�s_id: sti		; qui permettra de savoir si le programme est l� !
           nop 
	   push ds	; On sauve tout, sinon bonjour...
	   push es	;
	   push di
	   push si
	   push dx
           push cx
	   push bx
	   push ax
	   cmp byte ptr [drap],1	; Si 1 on devient transparent.
	   jz suite	; Saut � l'INT 21 toutes fonctions valid�es.
	   cmp ah,flag	; AH = 2C.
	   jnz suite	; Si non on traite les INT 21 normalement.
	   mov ax,sp	; On sauve le pointeur dans AX.
 incr:	   pop ds	; On pop le contenu de SP dans DS ce qui permet de
			; modifier plus facilement un octet qui se trouve en CS
	   cmp byte ptr ds:[adr_ip],1
           jnz incr	; Tant que l'on a pas trouv� le bon SEGMENT on POP.
	   mov byte ptr ds:[adr_ip],patch	; Si oui on patche...
	   mov byte ptr [drap],1h	; Et on n'y revient plus.....
	   mov sp,ax	; On replace la valeur d'origine dans SP.
suite:	   pop ax	; On n'oublie pas de restaurer toute la m�canique...
	   pop bx	;
	   pop cx	;
	   pop dx	;
	   pop si
	   pop di
	   pop es
	   pop ds 
           pushf	; Pushf et puis un CALL pour appeler l'INT 21 ceci
           cli		; pour simuler une instruction INT.
	   call   int21	; Appel de l'INT21 officielle.
 fin:	   sti
           ret    2     ; et on revient
 tsrint40  endp
 eor:

 ; ROUTINE D'INSTALLATION

 installe: mov    ax,3521h
	   int    21h
           cmp word ptr es:[bx+2],'RF'	; On teste la pr�sence de la signature.
           je     away                  ; si pr�sent on d�sinstalle.
	   mov    ax,cs			; CS --> DS
           mov    ds,ax			; DS = CS
           mov    ax,3521h              ; on detourne l'int 21h.
           int    21h			; sous-fonction 35.
           mov    word ptr [i40off],bx  ; L'offset se retrouve en BX.
           mov    i40seg,es		; Le segment en ES.
           mov    ax,2521h              ; Et on met l'ad. du resident
           mov    dx,offset tsrint40	; sous-fonction 25 dont SEG:OFF se
           int    21h			; trouve en DX <---( tsrint40 ).
           mov    dx,offset instok      ; Offset du message de fin.
           mov    ah,09			; Sorti du message...
           int    21h
           mov    ah,07			; Attente d'un caract�re au clavier.
	   int    21h
           mov    dx,eor-start+100h+15	; On r�serve la m�moire qui doit rester
           mov    cl,4			; en r�sident: DEBUT code - FIN code +
           shr    dx,cl			; 100h + 15. ( 100h car les zones data
           mov    al,0			; sont plac�es de 0 � 100h dans un com.
					; Puis d�calage de 4 � droite pour avoir
					; le r�sultat en nombre de paragraphe 
					; + 1 ( ou + 15 comme ci-dessus ).
           mov    ah,31h                ; Sortie et reservation
           int    21h                   ; de la m�moire.
 away:     mov    dx,word ptr es:i40off	; Restauration de OFF:SEG de l'INT 21
           mov    ax,word ptr es:i40seg	; d'origine.
           mov    ds,ax
           mov    ax,2521h		; Set vecteur de l' INT 21
           int    21h
           mov    bx,es
           mov    es,es:[2ch]
           mov    ah,49h		; On lib�re la m�moire.
           int    21h
           mov    es,bx
           mov    ah,49h
           int    21h
           push   cs			; Mettre CS dans DS 
           pop    ds
           mov    dx,offset elimine	; pointe sur d�but du message.
           xor    al,al
           mov    ah,9
           int    21h			; Sortir message.
           mov    ah,4ch			
           int    21h			; On revient au DOS.
 code      ends
           end    start